package com.fcat.common.user.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fcat.base.common.util.StrUtil;
import com.fcat.common.user.entity.User;
import com.fcat.common.user.enums.StateCode;
import com.fcat.common.user.exception.FeignRequestException;
import com.fcat.common.user.service.*;
import com.fcat.common.user.util.KeycloakUtil;
import com.fcat.common.user.vo.KeycloakUser;
import com.fcat.common.user.vo.ResourceInfo;
import com.fcat.common.user.vo.TokenQuery;
import com.fcat.springboot.core.util.SpringbootUtil;
import com.fcat.springboot.mybatis.util.JsonUtil;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("auth")
public class AuthController {

    private static Logger logger = LoggerFactory.getLogger(AuthController.class);
    @Autowired
    private DictService dictService;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserAuditService userAuditService;
    @Autowired
    private KeycloakService keycloakService;


    @Value("${token.realm}")
    private String realm;
    @Value("${token.client}")
    private String client;
    @Value("${token.clientSecret}")
    private String clientSecret;
    @Value("${token.clienId}")
    private String clienId;



    @ApiOperation(value = "登录", notes = "")
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.POST)
    public JSONObject getUserInfo() {
        String token = SpringbootUtil.getCurrentToken();
        KeycloakUser keycloakUser=null;
        try {
            keycloakUser=keycloakService.generateUser(token);
        }catch (FeignRequestException fe){
            if(fe.getStatus()==401){
                return JsonUtil.getFailJsonObject(StateCode.INVALID_TOKEN.getCode(),StateCode.INVALID_TOKEN.getMsg());
            }else{
                return JsonUtil.getFailJsonObject(fe.getStatus(), KeycloakUtil.getMsg(fe));
            }
        }catch (Exception e) {
            return JsonUtil.getFailJsonObject(KeycloakUtil.getMsg(e));
        }
        User user=userService.getUserByUsername(keycloakUser.getUsername());
        return keycloakService.getUserInfo(token,user.getKeycloakId());
    }


    @ApiOperation(value = "登录", notes = "")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public JSONObject login(HttpServletRequest request, @RequestParam("username") String username, @RequestParam("password") String password) {
        JSONObject paramObj = new JSONObject();
        JSONObject attributesObj = new JSONObject();
        username=username.toLowerCase();
        attributesObj.put("mac", "");
        paramObj.put("realm", realm);
        paramObj.put("client", client);
        paramObj.put("username", username);
        paramObj.put("password", password);
        paramObj.put("clientSecret", clientSecret);
        paramObj.put("attributes", attributesObj);
        User tmp = new User();
        tmp.setUsername(username);
        //先查找该用户是否在系统中存在
        User user = userService.selectOne(tmp);
        if (user == null || user.getDeleteFlag())
            return JsonUtil.getFailJsonObject(StateCode.ERROR_CHECK_PASSWORD_FAILED.getCode(),StateCode.ERROR_CHECK_PASSWORD_FAILED.getMsg());
        if (!user.getIsCheckPass()) return JsonUtil.getFailJsonObject("当前账户未审核");
        TokenQuery tokenQuery=new TokenQuery();
        tokenQuery.setClient(client);
        tokenQuery.setClientSecret(clientSecret);
        tokenQuery.setRealm(realm);
        tokenQuery.setUsername(username);
        tokenQuery.setPassword(password);
        JSONObject resultJsonObject=keycloakService.token(paramObj);

        int code = resultJsonObject.getIntValue("code");
        logger.info("登录用户："+username);
        if (code == 0) {
            String token=resultJsonObject.getString("data");
            logger.info("登录成功");
            userAuditService.saveLoginLog(request, resultJsonObject, username, "登录成功");
            //登录成功
            userService.processLoginToken(username, token);
            return JsonUtil.getSuccessJsonObject(token);
        } else {
            userAuditService.saveLoginLog(request, resultJsonObject, username, resultJsonObject.getString("msg"));
            if(code==-401){
                return JsonUtil.getFailJsonObject(StateCode.ERROR_CHECK_PASSWORD_FAILED.getCode(),StateCode.ERROR_CHECK_PASSWORD_FAILED.getMsg());
            }
            return JsonUtil.getFailJsonObject(code, resultJsonObject.getString("msg"));
        }
    }

    @ApiOperation(value = "登出测试", notes = "")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    public JSONObject logout() {
        return userService.logout(SpringbootUtil.parseToken().getUsername(), SpringbootUtil.getCurrentToken(), 1);
    }


    @ApiOperation(value = "2.2.1.获取用户的所有菜单资源（添加“常用导航图标”弹出桌面“添加应用”弹出）", notes = "")
    @GetMapping(value = "/user/getMainMenus")
    public JSONObject getMainMenus() {
        String token = SpringbootUtil.getCurrentToken();
        //先判断token是否有效
        JSONObject tmp=userService.isAccessToken(token);
        if(tmp.getIntValue("code")!=0){
            return tmp;
        }else{
            if(!tmp.getJSONObject("data").getBoolean("isAccessToken")){
                return JsonUtil.getFailJsonObject(StateCode.INVALID_TOKEN.getCode(), StateCode.INVALID_TOKEN.getMsg());
            }
        }

        JSONObject resultJsonObject = keycloakService.getResources(token);
        int code = resultJsonObject.getIntValue("code");
        //标题和序号
        Map<String, ResourceInfo> resourceMap = null;
        List<ResourceInfo> resourceInfoList = new ArrayList<>();
        if (code == 0) {
            resourceMap = resourceService.getExResources(resultJsonObject, resourceInfoList);
            if (resourceMap == null || resourceMap.size() == 0) {
                return JsonUtil.getSuccessJsonObject();
            }
            String httpIcon = dictService.getNameByValue("httpIcon");
            //获取
            List<ResourceInfo> level1List = resourceService.getSubResources(resourceMap, null);
            Collections.sort(level1List);
            System.err.println(level1List);
            JSONArray jsonArray = new JSONArray();
            for (ResourceInfo resourceInfo1 : level1List) {
                JSONObject jsonObject = new JSONObject();
                List<ResourceInfo> level2List = resourceService.getSubResources(resourceMap, resourceInfo1.getId());
                Collections.sort(level2List);
                System.err.println(level2List);
                //判断是否有三层
                List<ResourceInfo> testList = resourceService.getSubResources(resourceMap, level2List.get(0).getId());
                if (CollectionUtils.isEmpty(testList)) {//表示只有2层
                    jsonObject.put("isSecondLevel", true);
                    jsonObject.put("type", resourceInfo1.getDisplayName());
                    jsonObject.put("iconUrl", (httpIcon == null ? "" : httpIcon) + resourceInfo1.getDisplayName());
                    JSONArray level2Array = new JSONArray();
                    for (ResourceInfo resourceInfo2 : level2List) {
                        JSONObject level2Object = new JSONObject();
                        level2Object.put("resourceId", resourceInfo2.getResourceId());
                        level2Object.put("displayName", resourceInfo2.getDisplayName());
                        level2Object.put("uri", resourceInfo2.getUri());
                        level2Object.put("iconUri", resourceInfo2.getIconUri());
                        level2Array.add(level2Object);
                    }
                    jsonObject.put("resourceList", level2Array);
                } else {
                    jsonObject.put("isSecondLevel", false);
                    jsonObject.put("type", resourceInfo1.getDisplayName());
                    jsonObject.put("iconUrl", (httpIcon == null ? "" : httpIcon) + resourceInfo1.getDisplayName());
                    JSONArray level2Array = new JSONArray();
                    for (ResourceInfo resourceInfo2 : level2List) {
                        JSONObject level2Object = new JSONObject();
                        List<ResourceInfo> level3List = resourceService.getSubResources(resourceMap, resourceInfo2.getId());
                        Collections.sort(level3List);
                        level2Object.put("type", resourceInfo2.getDisplayName());
                        JSONArray level3Array = new JSONArray();
                        for (ResourceInfo resourceInfo3 : level3List) {
                            JSONObject level3Object = new JSONObject();
                            level3Object.put("resourceId", resourceInfo3.getResourceId());
                            level3Object.put("displayName", resourceInfo3.getDisplayName());
                            level3Object.put("uri", resourceInfo3.getUri());
                            level3Object.put("iconUri", resourceInfo3.getIconUri());
                            level3Array.add(level3Object);
                        }
                        level2Object.put("list", level3Array);
                        level2Array.add(level2Object);
                    }
                    jsonObject.put("resourceList", level2Array);
                }
                jsonArray.add(jsonObject);
            }
            return JsonUtil.getSuccessJsonObject(jsonArray);
        } else {
            return JsonUtil.getFailJsonObject(String.valueOf(code), resultJsonObject.getString("msg"));
        }
    }

    @ApiOperation(value = "3.6.2.校验用户token是否有效", notes = "")
    @RequestMapping(value = "/isAccessToken", method = RequestMethod.GET)
    public JSONObject isAccessToken() {
        String token = SpringbootUtil.getCurrentToken();
        if(StrUtil.isBlank(token)){
            return JsonUtil.getFailJsonObject("token不能为空");
        }
//        User user=userService.getUserByUsername(username);
//        if(user==null){
//            return JsonUtil.getFailJsonObject("当前用户不存在");
//        }
//        if(StrUtil.isBlank(user.getKeycloakId())){
//            return JsonUtil.getFailJsonObject("该登录名称系统不存在");
//        }
        return userService.isAccessToken(token);
//        Boolean isAccessToken=keycloakService.isAccessToken(Authorization,user);
//        JSONObject jsonObject=new JSONObject();
//        jsonObject.put("isAccessToken", isAccessToken);
//        return JsonUtil.getSuccessJsonObject(jsonObject);
    }

    @ApiOperation(value = "校验登录名是否存在", notes = "")
    @RequestMapping(value = "/checkUsername", method = RequestMethod.POST)
    public JSONObject checkUsername(String username) {
        User user = userService.getUserByUsername(username);
        JSONObject jsonObject = new JSONObject();
        if (user == null) {
            jsonObject.put("isExist", false);
        } else {
            jsonObject.put("isExist", true);
        }
        return JsonUtil.getSuccessJsonObject(jsonObject);
    }






    @ApiOperation(value = "获取所有菜单，测试用", notes = "")
    @GetMapping(value = "/user/getAllMainMenus")
    public JSONObject getMainMenusTest() {
        //先判断token是否有效
        JSONObject tmp=userService.isAccessToken(SpringbootUtil.getCurrentToken());
        if(tmp.getIntValue("code")!=0){
            return tmp;
        }else{
            if(!tmp.getJSONObject("data").getBoolean("isAccessToken")){
                return JsonUtil.getFailJsonObject(StateCode.INVALID_TOKEN.getCode(), StateCode.INVALID_TOKEN.getMsg());
            }
        }

        JSONObject resultJsonObject = keycloakService.getAllResources();
        int code = resultJsonObject.getIntValue("code");
        //标题和序号
        Map<String, ResourceInfo> resourceMap = null;
        List<ResourceInfo> resourceInfoList = new ArrayList<>();
        if (code == 0) {
            resourceMap = resourceService.getExResources(resultJsonObject, resourceInfoList);
            if (resourceMap == null || resourceMap.size() == 0) {
                return JsonUtil.getSuccessJsonObject();
            }
            String httpIcon = dictService.getNameByValue("httpIcon");
            //获取
            List<ResourceInfo> level1List = resourceService.getSubResources(resourceMap, null);
            Collections.sort(level1List);
            System.err.println(level1List);
            JSONArray jsonArray = new JSONArray();
            for (ResourceInfo resourceInfo1 : level1List) {
                JSONObject jsonObject = new JSONObject();
                List<ResourceInfo> level2List = resourceService.getSubResources(resourceMap, resourceInfo1.getId());
                Collections.sort(level2List);
                System.err.println(level2List);
                //判断是否有三层
                List<ResourceInfo> testList = resourceService.getSubResources(resourceMap, level2List.get(0).getId());
                if (CollectionUtils.isEmpty(testList)) {//表示只有2层
                    jsonObject.put("isSecondLevel", true);
                    jsonObject.put("type", resourceInfo1.getDisplayName());
                    jsonObject.put("iconUrl", (httpIcon == null ? "" : httpIcon) + resourceInfo1.getDisplayName());
                    JSONArray level2Array = new JSONArray();
                    for (ResourceInfo resourceInfo2 : level2List) {
                        JSONObject level2Object = new JSONObject();
                        level2Object.put("resourceId", resourceInfo2.getResourceId());
                        level2Object.put("displayName", resourceInfo2.getDisplayName());
                        level2Object.put("name", resourceInfo2.getName());
                        level2Object.put("uri", resourceInfo2.getUri());
                        level2Object.put("iconUri", resourceInfo2.getIconUri());
                        level2Array.add(level2Object);
                    }
                    jsonObject.put("resourceList", level2Array);
                } else {
                    jsonObject.put("isSecondLevel", false);
                    jsonObject.put("type", resourceInfo1.getDisplayName());
                    jsonObject.put("iconUrl", (httpIcon == null ? "" : httpIcon) + resourceInfo1.getDisplayName());
                    JSONArray level2Array = new JSONArray();
                    for (ResourceInfo resourceInfo2 : level2List) {
                        JSONObject level2Object = new JSONObject();
                        List<ResourceInfo> level3List = resourceService.getSubResources(resourceMap, resourceInfo2.getId());
                        Collections.sort(level3List);
                        level2Object.put("type", resourceInfo2.getDisplayName());
                        JSONArray level3Array = new JSONArray();
                        for (ResourceInfo resourceInfo3 : level3List) {
                            JSONObject level3Object = new JSONObject();
                            level3Object.put("resourceId", resourceInfo3.getResourceId());
                            level3Object.put("displayName", resourceInfo3.getDisplayName());
                            level3Object.put("name", resourceInfo3.getName());
                            level3Object.put("uri", resourceInfo3.getUri());
                            level3Object.put("iconUri", resourceInfo3.getIconUri());
                            level3Array.add(level3Object);
                        }
                        level2Object.put("list", level3Array);
                        level2Array.add(level2Object);
                    }
                    jsonObject.put("resourceList", level2Array);
                }
                jsonArray.add(jsonObject);
            }
            return JsonUtil.getSuccessJsonObject(jsonArray);
        } else {
            return JsonUtil.getFailJsonObject(String.valueOf(code), resultJsonObject.getString("msg"));
        }
    }
}
